// 所有权

pub fn main() {
    /// ## 类比理解
    /// ### 把数据想象成一本实体书：
    /// - 整数类型：像复印书页，原书和新复印件可以同时存在（Copy）
    /// - 字符串类型：像转交实体书，原主人（s1）交出后就不能再阅读（Move）
    /// ### 为什么这样设计？
    /// #### Rust为了防止多个变量同时操作同一块堆内存，从而避免：
    /// 1. 数据竞争（两个地方同时修改数据）
    /// 2. 内存泄漏（忘记释放内存）
    /// 3. 悬垂指针（访问已释放的内存）
    main1();
    main2();
    // 要解决 main2() 出现的所有权问题，可以通过以下方式解决：
    solve_1();
    solve_2();
    solve_3();
}

fn main1() {
    /// 原理：数字 3 是直接存储在栈上的小数据
    /// 行为：系统会自动复制一个新的 3 给 y（类似复印文件）
    /// 结果：x 和 y 各自持有独立的 3，互不影响
    let x = 3;
    let y = x;  // ✅ 允许
    println!("x = {}, y = {}", x, y);
}

fn main2() {
    /// 原理：字符串数据存储在堆内存，s1 只是保存了数据指针
    /// 行为：这里不是复制数据，而是转移数据所有权（类似房产过户）
    /// 结果：s1 变成空壳，不能再被使用（Rust 强制规定）
    let s1 = String::from("hello");
    let s2 = s1;  // ❌ 报错
    // println!("s1 = {}, s2 = {}", s1, s2);
}


fn solve_1() {
    let s1 = String::from("hello");
    let s2 = s1.clone();
    println!("s1 = {}, s2 = {}", s1, s2);
}

fn solve_2() {
    let s1 = &String::from("hello");
    let s2 = s1;
    println!("s1 = {}, s2 = {}", s1, s2);
}

fn solve_3() {
    let s1 = String::from("hello");
    let s2 = s1.as_str();
    println!("s1 = {}, s2 = {}", s1, s2);
}